package cn.itsource.hrm.service.impl;

import ch.qos.logback.core.encoder.ByteArrayUtil;
import cn.itsource.hrm.doc.CourseDoc;
import cn.itsource.hrm.doc.ESBaseQuery;
import cn.itsource.hrm.domain.Course;
import cn.itsource.hrm.domain.CourseDetail;
import cn.itsource.hrm.domain.CourseMarket;
import cn.itsource.hrm.dto.CourseSaveDTO;
import cn.itsource.hrm.feignclients.ESFeignClient;
import cn.itsource.hrm.mapper.CourseDetailMapper;
import cn.itsource.hrm.mapper.CourseMapper;
import cn.itsource.hrm.mapper.CourseMarketMapper;
import cn.itsource.hrm.query.CourseQuery;
import cn.itsource.hrm.service.ICourseService;
import cn.itsource.hrm.util.AjaxResult;
import cn.itsource.hrm.util.LoginInfo;
import cn.itsource.hrm.util.PageList;
import cn.itsource.hrm.util.UserContext;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.serializer.SerializerFeature;
import com.baomidou.mybatisplus.service.impl.ServiceImpl;
import org.elasticsearch.index.query.BoolQueryBuilder;
import org.elasticsearch.index.query.QueryBuilder;
import org.elasticsearch.index.query.QueryBuilders;
import org.elasticsearch.search.sort.FieldSortBuilder;
import org.elasticsearch.search.sort.SortOrder;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.elasticsearch.core.query.NativeSearchQueryBuilder;
import org.springframework.stereotype.Service;
import org.springframework.util.FileCopyUtils;
import org.springframework.util.StringUtils;

import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.util.Date;
import java.util.List;

/**
 * <p>
 *  服务实现类
 * </p>
 *
 * @author sk
 * @since 2020-02-21
 */
@Service
public class CourseServiceImpl extends ServiceImpl<CourseMapper, Course> implements ICourseService {

    @Autowired
    private CourseDetailMapper courseDetailMapper ;

    @Autowired
    private CourseMarketMapper courseMarketMapper ;

    @Autowired
    private ESFeignClient esFeignClient;

    @Autowired
    private ESBaseQuery esQuery;

    @Override
    public void saveOrUpdate(CourseSaveDTO courseSaveDTO) {
        //1.保存课程
        Course course = courseSaveDTO.getCourse();

        //课程状态
        course.setStatus(Course.STATUS_OFFLINE);
        //开课时间
        //假数据
        Date date = new Date();
        course.setStartTime(date);
        //节课时间
        course.setEndTime(date);

        //等级名字： ok
        //登录对象============
        //机构id :
        LoginInfo loginInfo = UserContext.getLoginInfo();
        course.setTenantId(loginInfo.getTenantId());
        //机构名字
        course.setTenantName(loginInfo.getTenantName());
        //创建课程的用户id
        course.setUserId(loginInfo.getUserId());

        //创建课程的用户名
        course.setUserName(loginInfo.getUserName());

        baseMapper.insert(course);

        //2.保存课程详情
        CourseDetail courseDetail = courseSaveDTO.getCourseDetail();
        courseDetail.setId(course.getId());
        courseDetailMapper.insert(courseDetail);

        //3.保存课程营销
        CourseMarket courseMarket = courseSaveDTO.getCourseMarket();

        courseMarket.setId(course.getId());
        courseMarket.setPriceOld(courseMarket.getPrice());

        //截止时间:假数据
        courseMarket.setExpires(date);

        courseMarketMapper.insert(courseMarket);

    }

    @Override
    public void onLineCourse(Long id) {
        //1.根据id查询课程
        Course course = baseMapper.selectById(id);

        //2.判断课程的状态
        if(course == null || course.getStatus() != Course.STATUS_OFFLINE){
            throw new RuntimeException("课程状态不处于下线状态");
        }

        //3.把课程添加到ES中
        //3.3.course-server通过Feign调用es-server

        //需要把course ,courseMarket 等等相关数据封装成 CourseDoc

        //课程营销
        CourseMarket courseMarket = courseMarketMapper.selectById(id);
        CourseDetail courseDetail = courseDetailMapper.selectById(id);

        CourseDoc courseDoc = new CourseDoc();
        //拷贝课程的属性到doc
        BeanUtils.copyProperties(course , courseDoc);
        //拷贝营销的属性到doc
        BeanUtils.copyProperties(courseMarket , courseDoc);
        //拷贝详情的属性到doc
        BeanUtils.copyProperties(courseDetail , courseDoc);
        //其他需要处理的属性
        courseDoc.setChargeName(courseMarket.getCharge()==0?"免费":"收费");
        //courseDoc.setOnlineDate(new Date());
        //预览数量
        courseDoc.setViewCount(100);
        //购买数量
        courseDoc.setBuyCount(200);

        AjaxResult ajaxResult = esFeignClient.save(courseDoc);
        if(ajaxResult.isSuccess()){
            //4.修改Mysql中的课程状态为：上线
            course.setStatus(Course.STATUS_ONLINE);
            baseMapper.updateById(course);
        }else{
            throw new RuntimeException("课程上线失败");
        }
    }

    @Override
    public void offLineCourse(Long id) {
        //1.根据id查询课程
        Course course = baseMapper.selectById(id);

        //2.判断课程状态必须为上线
        if(course == null || course.getStatus() != Course.STATUS_ONLINE){
            throw new RuntimeException("课程为空，或者课程状态不处于“上线");
        }

        //3.删除ES中的课程
        AjaxResult ajaxResult = esFeignClient.deleteById(id);

        if(!ajaxResult.isSuccess()){
            throw new RuntimeException("课程下线失败");
        }

        //4.修改mysql中的课程状态为：下线
        course.setStatus(Course.STATUS_OFFLINE);
        baseMapper.updateById(course);
    }


    @Override
    public PageList<CourseDoc> queryCourses(CourseQuery courseQuery) {
        return esFeignClient.searchCourse(courseQuery);

    }

    private ESBaseQuery createCourseQueryForES(CourseQuery courseQuery) {


        //添加条件===============================================================================================================
        //组合查询
        BoolQueryBuilder boolQueryBuilder = QueryBuilders.boolQuery();

        // keyword: "java"  : 查询 MathchQuery  - DSL查询
        if(StringUtils.hasLength(courseQuery.getKeyword())){
            boolQueryBuilder.must(QueryBuilders.matchQuery("name",courseQuery.getKeyword()));
        }

        //过滤
        List<QueryBuilder> filter = boolQueryBuilder.filter();

        //productType: ：termQuery
        if(courseQuery.getProductType() != null){
            filter.add(QueryBuilders.termQuery("courseTypeId",courseQuery.getProductType()));
        }

        //priceMax: null : rangeQuery
        if(courseQuery.getPriceMax() != null){
            filter.add(QueryBuilders.rangeQuery("price").lte(courseQuery.getPriceMax()));
        }

        //priceMin: null ：rangeQuery
        if(courseQuery.getPriceMin() != null){
            filter.add(QueryBuilders.rangeQuery("price").gte(courseQuery.getPriceMin()));
        }

        esQuery.withQuery(boolQueryBuilder);


        //添加分页
        esQuery.withPageable(PageRequest.of(courseQuery.getPage() - 1,courseQuery.getRows()));


        //添加排序===============================================================================================================
        // sortField:  ; sortType:==
        if(StringUtils.hasLength(courseQuery.getSortField())){

            String sortField = null;
            switch (courseQuery.getSortField().toLowerCase()){
                case "xl": sortField = "buyCount" ; break;
                case "xp": sortField = "onlineDate" ; break;
                case "jg": sortField = "price" ; break;
                case "rq": sortField = "viewCount" ; break;
                case "pl": sortField = "comment" ; break;
                default:sortField = "price" ;
            }

            //排序方式
            SortOrder sortOrder = SortOrder.DESC;
            if(StringUtils.hasLength(courseQuery.getSortType()) && courseQuery.getSortType().toLowerCase().equals("asc")){
                sortOrder = SortOrder.ASC;
            }


            esQuery.withSort(new FieldSortBuilder(sortField).order(sortOrder));
        }
        return esQuery;
    }




}

